/*
 * TouchGraph LLC. Apache-Style Software License
 *
 *
 * Copyright (c) 2002 Alexander Shapiro. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by
 *        TouchGraph LLC (http://www.touchgraph.com/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "TouchGraph" or "TouchGraph LLC" must not be used to endorse
 *    or promote products derived from this software without prior written
 *    permission.  For written permission, please contact
 *    alex@touchgraph.com
 *
 * 5. Products derived from this software may not be called "TouchGraph",
 *    nor may "TouchGraph" appear in their name, without prior written
 *    permission of alex@touchgraph.com.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL TOUCHGRAPH OR ITS CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 */

/**  LBNavigateUI. User interface for moving around the graph, as opposed
 *  to editing.
 *
 *  @author   Alexander Shapiro
 *  @version  1.20
 */

package abdn.graph.ontobrowser;

import com.touchgraph.graphlayout.interaction.*;
import com.touchgraph.graphlayout.*;

import javax.swing.*;
import javax.swing.event.*;
//import abdn.graph.growl.RenderGrowl;
import java.awt.event.*;
import java.util.HashSet;
//Packages needed for displaying the properties of an element
/*import abdn.taxon.property.ui.EntityPropertyPanel;
import abdn.taxon.entity.*;*/

public class OBNavigateUI
    extends TGUserInterface {

  //EntityPropertyPanel propertyPanel;
  TGPanel tgPanel;
  ESDOntoBrowser esdOntoBrowser;
  LBNavigateMouseListener ml;

  TGAbstractDragUI hvDragUI;
  TGAbstractDragUI dragZoomUI;

  TGAbstractClickUI hvScrollToCenterUI;
  OBNodeHintUI obNodeHintUI;
  DragNodeUI dragNodeUI;
  TGAbstractDragUI rotateDragUI;
  LocalityScroll localityScroll;

  JPopupMenu nodePopup;
  JPopupMenu clNodePopup;
  JPopupMenu clBackPopup;
  JPopupMenu edgePopup;
  Node popupNode;
  Edge popupEdge;
  ClusterNode clNode;

  //public OBNavigateUI(ESDOntoBrowser tglb, EntityPropertyPanel propPanel ) {
  public OBNavigateUI(ESDOntoBrowser tglb ) {
    esdOntoBrowser = tglb;
    tgPanel = esdOntoBrowser.getTGPanel();
    //propertyPanel = propPanel;
    localityScroll = esdOntoBrowser.localityScroll;

    hvDragUI = esdOntoBrowser.hvScroll.getHVDragUI();
    //rotateDragUI = esdOntoBrowser.rotateScroll.getRotateDragUI();
    dragZoomUI = esdOntoBrowser.zoomScroll.getDragZoomUI();
    hvScrollToCenterUI = esdOntoBrowser.hvScroll.getHVScrollToCenterUI();

    dragNodeUI = new DragNodeUI(tgPanel);

    obNodeHintUI = new OBNodeHintUI(tglb);

    ml = new LBNavigateMouseListener();

    setUpNodePopup();
    setUpEdgePopup();
    setUpBackPopup();
  }

  public void activate() {
    tgPanel.addMouseListener(ml);
    obNodeHintUI.activate();
  }

  public void deactivate() {
    tgPanel.removeMouseListener(ml);
    obNodeHintUI.deactivate();
  }

  class LBNavigateMouseListener
      extends MouseAdapter {

    public void mousePressed(MouseEvent e) {
      Node mouseOverN = tgPanel.getMouseOverN();
      clNode = tgPanel.getOpenCluster(e.getX(), e.getY());
      if (e.getModifiers() == MouseEvent.BUTTON1_MASK) {
        if (mouseOverN == null) {
          hvDragUI.activate(e);
        }
        else {
          dragNodeUI.activate(e);
        }
      }
      else if (e.getModifiers() == MouseEvent.BUTTON2_MASK) {
        //if (mouseOverN == null)
        dragZoomUI.activate(e);
      }
    }

    public void mouseClicked(MouseEvent e) {
      Node mouseOverN = tgPanel.getMouseOverN();
      Node select = tgPanel.getSelect();
      // if ((mouseOverN != null)&&(e.getModifiers() == MouseEvent.BUTTON1_MASK)&&(e.getClickCount()==2)){
      //double click first button

      //}
      //else objectCategory
      if ( (e.getModifiers() & MouseEvent.BUTTON1_MASK) != 0) {
        if (mouseOverN != null)
        //	&& !(mouseOverN instanceof OBRelationNode)
        //&& ((OBObjectNode) mouseOverN).objectCategory < 5)
        {
          if (mouseOverN != select) {
            esdOntoBrowser.setSelect( (OBNode) mouseOverN);
            if (mouseOverN instanceof OBObjectNode) {
              //propertyPanel.displayProperty( ( OBNode) mouseOverN );
              //System.out.println("Node activated: " + ( (OBNode) mouseOverN).getName() );
              tgPanel.setLocale( mouseOverN, localityScroll.getRadius());
              //hvScrollToCenterUI.activate(e);
            }
          }
          else if (mouseOverN instanceof OBNode) {
            //esdOntoBrowser.processNodeUrl((OBNode)mouseOverN);
          }
        }
      }
    }

    public void mouseReleased(MouseEvent e) {
      //if (e.isPopupTrigger()) {
      if (e.getModifiers() == MouseEvent.BUTTON3_MASK) {
        popupNode = tgPanel.getMouseOverN();
        popupEdge = tgPanel.getMouseOverE();
        if (popupNode != null) {
          tgPanel.setMaintainMouseOver(true);
          obNodeHintUI.deactivate();
          if (popupNode instanceof ClusterNode) {
            clNodePopup.show(e.getComponent(), e.getX(), e.getY());
          }
          else {
            JPopupMenu nPopupMenu =
                esdOntoBrowser.guiPolicy.getNodePopup(
                (OBNode) popupNode);
            if (esdOntoBrowser.rtPolicy instanceof RTPolicyJS) {
              ( (RTPolicyJS) esdOntoBrowser.rtPolicy).updateMenu(
                  nPopupMenu,
                  (OBNode) popupNode);
            }

            nPopupMenu.show(e.getComponent(), e.getX(), e.getY());
          }
          //nodePopup.show(e.getComponent(), e.getX(), e.getY());
        }
        else if (popupEdge != null) {
          tgPanel.setMaintainMouseOver(true);
          obNodeHintUI.deactivate();
          edgePopup.show(e.getComponent(), e.getX(), e.getY());
        }
        else if (clNode != null) {
          clBackPopup.show(e.getComponent(), e.getX(), e.getY());
        }
        else {
          tgPanel.setMaintainMouseOver(true);
          esdOntoBrowser.guiPolicy.showOBPopup(e);
        }
      }
    }
  }

  private void setUpNodePopup() {
    JMenuItem menuItem;
    clNodePopup = new JPopupMenu();

    /*
     menuItem = new JMenuItem("Expand Node");
     ActionListener expandAction = new ActionListener() {
       public void actionPerformed(ActionEvent e) {
        if(popupNode!=null) {
         tgPanel.expandNode(popupNode);
        }
       }
      };
     menuItem.addActionListener(expandAction);
     nodePopup.add(menuItem);
     menuItem = new JMenuItem("Hide Node");
     ActionListener hideAction = new ActionListener() {
       public void actionPerformed(ActionEvent e) {
        Node select = tgPanel.getSelect();
        if(popupNode!=null) {
         //tgPanel.hideNode(popupNode, select);
        }
       }
      };
     menuItem.addActionListener(hideAction);
     nodePopup.add(menuItem);
     *
     *
     *
     */

    menuItem = new JMenuItem("Unfold Cluster");
    ActionListener unfoldAction = new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        if (popupNode != null) {
          ( (ClusterNode) popupNode).unfoldCluster(tgPanel);
          tgPanel.repaint();
          tgPanel.resetDamper();
        }
      }
    };

    menuItem.addActionListener(unfoldAction);
    clNodePopup.add(menuItem);

    /*
       menuItem = new JMenuItem("Select for Search");
       ActionListener queryAction = new ActionListener() {
      public void actionPerformed(ActionEvent e) {
       Node select = tgPanel.getSelect();
       if(popupNode!=null) {
         if(popupNode instanceof OBObjectNode)
         esdOntoBrowser.queryNode( popupNode.getID(),popupNode.getLabel(), 0);
               else if(popupNode instanceof OBRelationNode)
         esdOntoBrowser.queryNode( popupNode.getID(),popupNode.getLabel(), 1);
       }
      }
     };
       menuItem.addActionListener(queryAction);
     nodePopup.add(menuItem);
     */

    menuItem = new JMenuItem("Show More");
    menuItem.addActionListener(esdOntoBrowser.showMoreAction);
    clNodePopup.add(menuItem);

    menuItem = new JMenuItem("Show Less");
    menuItem.addActionListener(esdOntoBrowser.showLessAction);
    clNodePopup.add(menuItem);

    menuItem = new JMenuItem("Toggle Controls");
    menuItem.addActionListener(esdOntoBrowser.toggleControlsAction);
    clNodePopup.add(menuItem);

    /*
     menuItem = new JMenuItem("Select Node");
     ActionListener selectAction = new ActionListener() {
       public void actionPerformed(ActionEvent e) {
        if(popupNode!=null) {
         tgPanel.setSelect(popupNode);
        }
       }
      };
     menuItem.addActionListener(selectAction);
     nodePopup.add(menuItem);
     */

    clNodePopup.addPopupMenuListener(new PopupMenuListener() {
      public void popupMenuCanceled(PopupMenuEvent e) {
      }

      public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
        tgPanel.setMaintainMouseOver(false);
        tgPanel.setMouseOverN(null);
        tgPanel.repaint();
        obNodeHintUI.activate();
      }

      public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
      }
    });

  }

  private void setUpBackPopup() {
    clBackPopup = new JPopupMenu();
    JMenuItem menuItem;
    /*
     menuItem = new JMenuItem("Collapse  ");
     ActionListener collapseClusterAction = new ActionListener() {
      public void actionPerformed(ActionEvent e) {
       clNode.collapsCluster(tgPanel);
       tgPanel.repaint();
       tgPanel.resetDamper();
      }
     };
     menuItem.addActionListener(collapseClusterAction);
     clBackPopup.add(menuItem);*/

    menuItem = new JMenuItem("Show More");
    menuItem.addActionListener(esdOntoBrowser.showMoreAction);
    clBackPopup.add(menuItem);

    menuItem = new JMenuItem("Show Less");
    menuItem.addActionListener(esdOntoBrowser.showLessAction);
    clBackPopup.add(menuItem);

    menuItem = new JMenuItem("Toggle Controls");
    menuItem.addActionListener(esdOntoBrowser.toggleControlsAction);
    clBackPopup.add(menuItem);

    clBackPopup.addPopupMenuListener(new PopupMenuListener() {
      public void popupMenuCanceled(PopupMenuEvent e) {
      }

      public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
        tgPanel.setMaintainMouseOver(false);
        tgPanel.setMouseOverN(null);
        tgPanel.repaint();
        obNodeHintUI.activate();
      }

      public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
      }
    });

  }

  private void setUpEdgePopup() {
    edgePopup = new JPopupMenu();
    JMenuItem menuItem;

    menuItem = new JMenuItem("Hide Edge");
    ActionListener hideAction = new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        if (popupEdge != null) {
          tgPanel.hideEdge(popupEdge);
        }
      }
    };

    menuItem.addActionListener(hideAction);
    edgePopup.add(menuItem);

    edgePopup.addPopupMenuListener(new PopupMenuListener() {
      public void popupMenuCanceled(PopupMenuEvent e) {
      }

      public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
        tgPanel.setMaintainMouseOver(false);
        tgPanel.setMouseOverE(null);
        tgPanel.repaint();
        obNodeHintUI.activate();
      }

      public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
      }
    });
  }

}